/*
@title: laser tag
@description: Control two characters at the same time and try to get both of them on the green goal spaces.
@author: leo
@tags: ['strategy']
@addedOn: 2022-07-14

Instructions:

Get to the green block.
Dont get hit by the lasers.
*/

const player1 = "0"
const player2 = "1"
const wall = "2"
const upLaser = "3"
const downLaser = "4"
const leftLaser = "5"
const rightLaser = "6"
const vert = "7"
const horz = "8"
const target = "9"
const background = "b"

setLegend(
  [ player1, bitmap`
................
................
........333.....
.......33..33...
......3.....33..
....33.......3..
...33.3....3..3.
...3..........3.
...33........33.
....3........3..
.....33.....33..
......333..33...
......3.3333....
......3....3....
.....33....333..
....33.......3..` ],
  [ player2, bitmap`
................
................
................
.....5555.5.....
.....5....55....
....55......5...
....5.5..5..5...
....5.......5...
....5......55...
....5555.555....
......5555......
......5..5......
......5..5......
......5..5......
...5555..5555...
.........55.....` ],
  [ wall, bitmap`
0000000000000000
00............00
000..........000
0.00........00.0
0..00......00..0
0...0.....00...0
0....0...0.....0
0.....0.0......0
0.....00.......0
0....00.0......0
0....0...0.....0
0...0.....0....0
0..0.......00..0
0.0.........00.0
00...........000
0000000000000000` ],
  [ upLaser, bitmap`
................
................
.........3......
........33......
.......333......
......33.33.....
....333.333.....
...33...3..3....
..33....3...33..
........3....3..
........3....33.
........3.......
........3.......
........3.......
................
................` ],
  [ rightLaser, bitmap`
................
................
................
.......3........
.......33.......
........33......
.........33.....
...........3....
..33333333333...
...........33...
...........3....
..........3.....
........33......
.......33.......
................
................` ],
  [ downLaser, bitmap`
................
................
.......3........
.......3........
.......3........
.......3........
.......3........
.......3........
.......3........
.......3........
...3...3.....3..
....3..3....3...
.....3.3..33....
.....3.3.3......
......333.......
.......3........` ],
  [ leftLaser, bitmap`
................
................
................
................
......3.........
.....3..........
...33...........
..3.............
.3333333333333..
.3..............
..3.............
...3............
....3...........
.....3..........
......3.........
.......3........` ],
  [ vert, bitmap`
................
................
................
.......3........
.......3........
.......3........
.......3........
.......3........
.......3........
.......3........
.......3........
.......3........
.......3........
................
................
................` ],
  [ horz, bitmap`
................
................
................
................
................
................
................
..333333333333..
................
................
................
................
................
................
................
................` ],
  [ target, bitmap`
................
................
................
...4444444444...
...44....4..4...
...4.4...4..4...
...4.4..4...4...
...4..4.4...4...
...4..44....4...
...4...4...4....
...4..4.4..4....
...4..4.4..4....
...4.4...4.4....
...4.4...4.4....
...44444..44....
........4444....`],
  [ background, bitmap`
LLLLLLLLLLLLLLLL
LLLLLLLLLLLLLLLL
LLLLLLLLLLLLLLLL
LLLL1LLLLLLLLLLL
LLLLLLLLLLL1L11L
LLL1LLLLLLLLLLLL
LLLLLLLLLLLLLLLL
LLLLLLLLLLLLLLLL
LLLLLLLLLLLLL1LL
LLL1LLLLLLLL1LLL
L1LLLLLLLLLLLLLL
L1LLL1LLLLL1LLLL
LLLLLLLLLL1LLLLL
LLLLL1LLLLLLLLLL
LLLLLLLLLLLLLLLL
LLLLLLLLLLLLLLLL`],
  [ "u", bitmap`
................
................
......0.0.......
......0.0.......
......0.0.......
......0.0.......
......000.......
................
..0..000.00.00..
..0..0.0.0..0...
..0..0.0.00.00..
..0..0.0..0.0...
..00.000.00.00..
................
................
................`],
  [ "w", bitmap`
................
................
......0.0.......
......0.0.......
......0.0.......
......0.0.......
......000.......
................
................
.0...0.000.0..0.
.0...0..0..00.0.
.0.0.0..0..0.00.
.0.0.0..0..0.00.
.00000.000.0..0.
................
................`]
)

// setBackground(background);

setSolids([
    player1, 
    player2, 
    wall, 
    upLaser,
    downLaser,
    leftLaser,
    rightLaser
]);

let level = 0;
const levels = [
    map`
...7...
9..7...
9..7.2.
60.7.1.
...3...`,
    map`
9..7...
6888888
9..7.2.
.0.7.1.
.2.3...`,
    map`
...49
..1..
22..5
9....
0....`,
    map`w`
];

let activePlayer = player1;

const getActivePlayer = () => getFirst(activePlayer);

setMap(levels[level]);
initLasers();

onInput("w", _ => {
    const p1 = getFirst(player1);
    const p2 = getFirst(player2);

    if (!p1 || !p2) return;

    if (p1.y < p2.y) {
        p1.y -= 1;
        p2.y -= 1;
    } else {
        p2.y -= 1;
        p1.y -= 1;
    }

})

onInput("s", _ => {
    const p1 = getFirst(player1);
    const p2 = getFirst(player2);

    if (!p1 || !p2) return;

    if (p1.y > p2.y) {
        p1.y += 1;
        p2.y += 1;
    } else {
        p2.y += 1;
        p1.y += 1;
    }
})

onInput("a", _ => {
    const p1 = getFirst(player1);
    const p2 = getFirst(player2);

    if (!p1 || !p2) return;

    if (p1.x < p2.x) {
        p1.x -= 1;
        p2.x -= 1;
    } else {
        p2.x -= 1;
        p1.x -= 1;
    }
})

onInput("d", _ => {
    const p1 = getFirst(player1);
    const p2 = getFirst(player2);

    if (!p1 || !p2) return;
    
    if (p1.x > p2.x) {
        p1.x += 1;
        p2.x += 1;
    } else {
        p2.x += 1;
        p1.x += 1;
    }
})

/* reset level */
onInput("j", _ => setMap(levels[level]));

function isJustLaser(t) {
  return t.length === 1 
    && (t.map(x => x.type).includes(vert)
        || t.map(x => x.type).includes(horz)
        || t.map(x => x.type).includes(player2));
}

function initLasers() {
    // remove all lasers
    getAll(horz).forEach(s => s.remove());
    getAll(vert).forEach(s => s.remove());

    // add lasers back in
    getAll(upLaser).forEach(up => {
        let { x, y } = up;
        y -=1
        while (true) {
            if (y < 0) break;
            const t = getTile(x, y);
            if (t.length === 0 || isJustLaser(t)) addSprite(x, y, vert)
            else break;
            y--;
        }
    })

    getAll(downLaser).forEach(down => {
        let { x, y } = down;
        y +=1
        while (true) {
            if (y >= height()) break;
            const t = getTile(x, y);
            if (t.length === 0 || isJustLaser(t)) addSprite(x, y, vert)
            else break;
            y++;
        }
    })

    getAll(rightLaser).forEach(right => {
        let { x, y } = right;
        x +=1
        while (true) {
            if (x >= width()) break;
            const t = getTile(x, y);
            if (t.length === 0 || isJustLaser(t)) addSprite(x, y, horz)
            else break;
            x++;
        }
    })

   getAll(leftLaser).forEach(left => {
        let { x, y } = left;
        x -=1
        while (true) {
            if (x < 0) break;
            const t = getTile(x, y);
            if (t.length === 0 || isJustLaser(t)) addSprite(x, y, horz)
            else break;
            x--;
        }
    })
}

afterInput(_ => {
    initLasers();
    let finished = true;
    getAll(target).forEach(t => {
        finished = getTile(t.x, t.y).length === 2 && finished;
    })

    const dead = [
        ...tilesWith(player2, vert),
        ...tilesWith(player2, horz)
    ]
    if (dead.length) {
        getFirst(player2).remove()
        setMap(map`u`)
    }

    if (finished && level+1 < levels.length) setMap(levels[++level]);
});
